package com.goblin.model.socket;

import com.goblin.model.uaa.po.User;
import com.goblin.security.AuthorityStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@ServerEndpoint(value = "/websocket/topic/{token}", encoders = {Encode.class})
@Component
public class SocketServer {
    private static Logger logger = LoggerFactory.getLogger(SocketServer.class);

    private static Session session;
    private static Map<Integer, Session> sessionPool = new HashMap<>();
    private static Map<String, String> sessionIds = new HashMap<String, String>();
    private static Map<Integer, Session> logoutSessionPool = new HashMap<>();

    @OnOpen
    public void open(Session session, @PathParam("token") String token) throws IOException {
        this.session = session;

        List list = AuthorityStore.getAuth(token);
        User user = null;
        if (list != null) {
            user = (User) list.get(1);
            logger.info("{}, {}, {} -> 已登录并建立链接.", user.getNickName(), user.getId(), token);
        } else {
            logger.info("未登录禁止连接");
            this.session.close();
            return;
        }

        if (sessionPool.containsKey(user.getId())) {
            Session s = sessionPool.get(user.getId());
            logoutSessionPool.put(user.getId(), s);
            sessionIds.remove(s.getId());
        }

        sessionPool.put(user.getId(), session);
        sessionIds.put(session.getId(), user.getId().toString());
    }

    @OnMessage
    public void onMessage(String message) {
        logger.debug("当前发送人sessionid为" + this.session.getId() + "发送内容为" + message);
    }

    @OnClose
    public void onClose() {
        try {
            removeLoginInfo();
        } catch (Exception ex) {
            logger.warn("连接关闭异常");
        }
    }

    private void removeLoginInfo() {
        String userId = sessionIds.get(this.session.getId());
        sessionPool.remove(userId);
        sessionIds.remove(this.session.getId());
        logger.info("{} 断开连接 -> ", userId);
    }

    @OnError
    public void onError(Session session, Throwable error) {
        try {
            removeLoginInfo();
        } catch (Exception ex) {
            logger.warn("连接异常退出");
        }
    }

    public static void sendMessage(Object message, Integer userId)
            throws Exception {
        logger.debug("send to: {}", userId);
        logger.debug("message details: {}", message.toString());

        Session s = sessionPool.get(userId);

        if (s == null) {
            logger.debug("{} -> 不能够通知消息，用户不在线", message);
        }
        if (s != null) {
            try {
                s.getBasicRemote().sendObject(message);
            } catch (IOException ex) {
                logger.warn("消息推送失败 -> {0}, {1}", ex.getStackTrace(), message);
            }
            logger.info("消息推送成功 -> {}", message);
        }
    }

}
